//----------------------------------------------------------------------------------------------------------------------
/// \file
/// <summary> API and data types for using data in TestDataManagementSystem </summary>
// Copyright (c) Microsoft Corporation.  All Rights Reserved.
//----------------------------------------------------------------------------------------------------------------------
#pragma once
#include "TDMS.h"
#include "WexTypes.h"

#include <BaseTyps.h>
#include <sal.h>


namespace WEX { namespace TestDataManagementSystem
{

    class TestCorpusPrivate;

    /// <summary>
    ///  Flags to specify deployment behaviors
    /// <\summary>
    namespace DeploymentBehaviors
    {
       enum Behaviors
       {
            /// <summary>
            /// Default behavior.
            /// <\summary>
            None = 0x0000,

            /// <summary>
            /// If files exist, silently overwrite these.
            /// <\summary>
            OverwriteFiles = 0x0001,

            /// <summary>
            /// Disable automatic cleanup of deployed files upon object destruction.
            /// <\summary>
            DisableAutoCleanup = 0x0002
       };
    }

    inline DeploymentBehaviors::Behaviors& operator|=(DeploymentBehaviors::Behaviors& lhs, const DeploymentBehaviors::Behaviors& rhs)
    {
        lhs = static_cast<DeploymentBehaviors::Behaviors>((static_cast<int>(lhs) | static_cast<int>(rhs)));
        return lhs;
    }

    inline DeploymentBehaviors::Behaviors operator|(DeploymentBehaviors::Behaviors lhs, const DeploymentBehaviors::Behaviors& rhs)
    {
        return lhs |= rhs;
    }

    /// <summary>
    ///  Flags to specify removal behaviors.
    /// <\summary>
    namespace RemovalBehaviors
    {
       enum Behaviors
       {
            /// <summary>
            /// Default behavior.
            /// <\summary>
            None = 0x0000,

            /// <summary>
            /// No errors, if a deployed file does not exist (ERROR_PATH_NOT_FOUND or ERROR_FILE_NOT_FOUND).
            /// <\summary>
            IgnoreNotFoundFiles = 0x0001
       };
    }

    inline RemovalBehaviors::Behaviors& operator|=(RemovalBehaviors::Behaviors& lhs, const RemovalBehaviors::Behaviors& rhs)
    {
        lhs = static_cast<RemovalBehaviors::Behaviors>((static_cast<int>(lhs) | static_cast<int>(rhs)));
        return lhs;
    }

    inline RemovalBehaviors::Behaviors operator|(RemovalBehaviors::Behaviors lhs, const RemovalBehaviors::Behaviors& rhs)
    {
        return lhs |= rhs;
    }

    /// <summary>
    ///  API to retrive data from Test Data Management System.
    /// <\summary>
    /// \code
    /// Example:
    ///     Corpus corpus(2108, 2);
    ///     HRESULT hr = corpus.Deploy(L"C:\\MyLocalDir");
    ///     hr = corpus.Remove();
    /// \endcode
    class TDMS_API Corpus sealed
    {
    public:
        Corpus(unsigned long corpusId, unsigned long revisionId);
        Corpus(unsigned long corpusId, unsigned long revisionId, _In_z_ const wchar_t* pszSubsetSelectionQuery);
        ~Corpus();
        
        /// <summary>
        /// Deploys corpus to a certain location. Note, you can only deploy files once (to a single location).
        /// <\summary>
        HRESULT Deploy(_In_z_ const wchar_t* pszDeploymentLocation, DeploymentBehaviors::Behaviors deploymentBehaviors = DeploymentBehaviors::None);
        
        /// <summary>
        /// Removes the deployed files from the location where the files where deployed by a call to Deploy.
        /// <\summary>
        HRESULT Remove(RemovalBehaviors::Behaviors removalBehaviors = RemovalBehaviors::None);
        
        #ifdef TDMS_EXPORTS
        Corpus(unsigned long corpusId, unsigned long revisionId, _In_z_ const __wchar_t* pszSubsetSelectionQuery);
        HRESULT Deploy(_In_z_ const __wchar_t* pszDeployLocation, DeploymentBehaviors::Behaviors deploymentBehaviors = DeploymentBehaviors::None);
        #endif

    private:
        Corpus(const Corpus& other); // non-implemented
        Corpus& operator=(Corpus& other); // non-implemented
        Corpus(); // non-implemented

        TestCorpusPrivate* m_corpus;
        HRESULT m_initializedCom;
    };

    
} /* TestExecution */ } /* namespace WEX */
